package es.ignapziriza.ccrypto.ciphers.transposition;

import es.ignapziriza.ccrypto.Cipher;
import es.ignapziriza.ccrypto.CipheredText;

/**
 * Caesar Ciphering.
 * 
 * @see CipheredText
 * @see Cipher
 * @author ignapziriza
 * 
 */
public class CaesarCipher extends CipheredText implements Cipher {

	protected int offset;
	protected int alphabetLength;

	/**
	 * Constructor.
	 * 
	 * @param isItTheSpanishOne
	 *            uses the spanish or the english alphabet.
	 * @author ignapziriza
	 */
	public CaesarCipher(boolean isItTheSpanishOne) {
		if (isItTheSpanishOne) {
			alphabetLength = 27;
		} else {
			alphabetLength = 26;
		}
		offset = 3;
	}

	/**
	 * Constructor
	 * 
	 * @param isItTheSpanishOne
	 *            uses the spanish or the english alphabet.
	 * @param offset
	 *            the offset set for a variant of the Caesar Ciphering.
	 * @author ignapziriza
	 */
	public CaesarCipher(boolean isItTheSpanishOne, int offset) {
		if (isItTheSpanishOne) {
			alphabetLength = 27;
		} else {
			alphabetLength = 26;
		}
		this.offset = offset;
	}

	@Override
	public void cipher(String textToCipher) {
		cipheredText = encode(textToCipher);
	}

	@Override
	public void decipher(String textToCipher) {
		offset = -offset;
		cipheredText = encode(textToCipher);

	}

	private String encode(String textToCipher) {
		offset = offset % alphabetLength + alphabetLength;
		StringBuilder encoded = new StringBuilder();
		for (char i : textToCipher.toLowerCase().toCharArray()) {
			if (Character.isLetter(i)) {
				int j = (i - 'a' + offset) % alphabetLength;
				encoded.append((char) (j + 'a'));
			} else {
				encoded.append(i);
			}
		}
		return encoded.toString().toUpperCase();
	}

}
